<template>
	<div
		class="base-image"
		:style="{ width: (props.width) + 'px', height: ( props.height) + 'px', background: (props.bgColor) || 'none' ,borderRadius:(localRadius)+'px' ,cursor: 'pointer'}"
		@click.stop="handleClick"
		@mouseenter="mouseenter"
		@mouseleave="mouseleave"
	>
		<img
			:src="!hover?realSrc:realHoverSrc"
			:style="imgStyle"
			:class="['base-image-img', localImgClass]"
			draggable="false"
		/>
	</div>
</template>

<script setup lang="ts">
import { ref, computed, watch, CSSProperties } from 'vue'
import { ComponentInstance } from '@/types/visual-app'
import notFoundImg from '@/assets/img/state/404.png'
import { useDynamicComponentStore } from '@/store/dynamicComponent'
import { useVisualStore } from '@/store/visual'
import { axiosInstance } from '@/utils/http/index'
import { transformData} from '@/utils/visual/ConfigUtil'
const BASE_API = axiosInstance.defaults.baseURL
const dynamicComponentStore = useDynamicComponentStore()
const dynamicVisualStore = useVisualStore()
const props = defineProps<ComponentInstance>()
const loading = ref(true)
const error = ref(false)

// 本地变量响应 props.config
const localSrc = ref(props.config?.src || notFoundImg)
const localHover = ref(props.config?.hover || notFoundImg)
const visible = ref<boolean>(props.visible ?? false)
const localWidth = ref(props.config?.width ?? 200)
const localHeight = ref(props.config?.height ?? 120)
const localRadius = ref(props.config?.radius ?? 0)
const localAlpha = ref(props.config?.alpha ?? 1)
const localCss = ref(props.config?.css ?? '')
const localObjectFit = ref(props.config?.objectFit || 'cover')
const localPreview = ref(props.config?.preview ?? true)
const localFallback = ref(props.config?.fallback || '')
const localAlt = ref(props.config?.alt || '')
const localImgClass = ref(props.config?.imgClass || '')
const localBoxShadow = ref(props.config?.boxShadow || '')
const localTransform = ref(props.config?.transform || '')
const localBindings = ref<any[]>(Array.isArray(props.bindings) ? [...props.bindings] : [])

watch(() => props.config?.src, val => {
  localSrc.value = val || ''
  loading.value = true
  error.value = false
})

watch(() => props.config?.hover, val => {
  localHover.value = val || ''
})

const realSrc = computed(() => {
  if (! localSrc.value) {
    return notFoundImg;
  } else if (/^(https?:)?\/\//i.test( localSrc.value)) {
    return  localSrc.value
  } else {
    return BASE_API + '/visual/material/image/' + localSrc.value + '?' + new Date().getTime();
  }
})

const realHoverSrc = computed(() => {
  if (! localHover.value) {
    return notFoundImg;
  } else if (/^(https?:)?\/\//i.test( localHover.value)) {
    return  localHover.value
  } else {
    return BASE_API + '/visual/material/image/' + localHover.value + '?' + new Date().getTime();
  }
})

watch(() => props.config?.width, val => { localWidth.value = val ?? 200 })
watch(() => props.config?.height, val => { localHeight.value = val ?? 120 })
watch(() => props.config?.radius, val => { localRadius.value = val ?? 0 })
watch(() => props.config?.objectFit, val => { localObjectFit.value = val || 'cover' })
watch(() => props.config?.preview, val => { localPreview.value = val ?? true })
watch(() => props.config?.fallback, val => { localFallback.value = val || '' })
watch(() => props.config?.alt, val => { localAlt.value = val || '' })
watch(() => props.config?.imgClass, val => { localImgClass.value = val || '' })
watch(() => props.config?.alpha, val => { localAlpha.value = val ?? 1 })
watch(() => props.config?.css, val => { localCss.value = val || '' })
watch(() => props.config?.boxShadow, val => { localBoxShadow.value = val || '' })
watch(() => props.config?.transform, val => { localTransform.value = val || '' })

const onLoad = () => {
  loading.value = false
  error.value = false
}
const onError = () => {
  loading.value = false
  error.value = true
}

const emit = defineEmits<{
  (e: 'click', data:any): void,
  (e: 'update:visible', state:boolean): void
}>()

const hover=ref<boolean>(false);
const mouseenter=()=>{
	hover.value=true;
}

const mouseleave=()=>{
	hover.value=false;
}


const containerStyle = computed(() => ({
  width: typeof localWidth.value === 'number' ? localWidth.value + 'px' : localWidth.value,
  height: typeof localHeight.value === 'number' ? localHeight.value + 'px' : localHeight.value,
  borderRadius: typeof localRadius.value === 'number' ? localRadius.value + 'px' : localRadius.value,
  overflow: 'hidden',
  cursor: localPreview.value ? 'pointer' : undefined,
  ...(props.config?.style || {})
}))

const imgStyle = computed<CSSProperties>(() => {
  const baseStyle: CSSProperties = {
    width: '100%',
    height: '100%',
    objectFit: localObjectFit.value as CSSProperties['objectFit'],
    display: 'block',
    opacity: localAlpha.value,
    borderRadius:localRadius.value,
	boxShadow:localBoxShadow.value,
	transform:localTransform.value
  }
  
  // 安全地解析 CSS 配置
  if (localCss.value && localCss.value.trim()) {
    try {
      const cssConfig = JSON.parse(localCss.value)
      if (typeof cssConfig === 'object' && cssConfig !== null) {
        return { ...baseStyle, ...cssConfig }
      }
    } catch (error) {
      console.warn('CSS 配置解析失败:', error)
    }
  }
  
  return baseStyle
})

const handleClick = () => {
  dynamicVisualStore.triggerEventMethods(localBindings.value,'click',[]);
}

watch(() =>props.visible, val => {
	visible.value=val|| false
}, { immediate: true })


const hide=()=>{
	emit('update:visible', false); 
}

const show=()=>{
	emit('update:visible', true); 
}


defineExpose({
  show,
  hide
})

</script>

<style scoped>
.base-image {
  position: relative;
  display: inline-block;
  /* background: #f5f7fa; */
  user-select: none;
}
.base-image-loading,
.base-image-error {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #bbb;
  font-size: 14px;
  background: rgba(245,247,250,0.85);
  z-index: 2;
}
</style>
